package com.yuandian.middle.platform.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.yuandian.api.middle_platform.po.HttpResultVo;
import com.yuandian.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.URIBuilder;

import javax.annotation.Nullable;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 通用http工具封装
 * <p>
 *
 * @author VaeTang
 * @date 2020/07/01
 * @since 1.0.0
 */
@Slf4j
public class HttpUtil {

	public static void main(String[] args) throws Exception {
		HttpResultVo httpResultVo = doPost("https://www.baidu.com", null);
		System.out.println(httpResultVo);
	}

	public static HttpResultVo doPost(String httpUrl, @Nullable String param) throws Exception {
		return doPost( httpUrl, null,  param);
	}

    /**
     * Http post请求
	 * @param httpUrl 连接
	 * @param headMap 请求头
     * @param param 请求参数
     */
    public static HttpResultVo doPost(String httpUrl, Map<String, String> headMap, @Nullable String param) throws Exception {
		HttpResultVo httpResultVo = new HttpResultVo();
        StringBuffer result = new StringBuffer();
        HttpURLConnection connection = null;
        OutputStream os = null;
        InputStream is = null;
        BufferedReader br = null;

        try {
            URL url = new URL(httpUrl);								// 创建连接对象
            connection = (HttpURLConnection) url.openConnection();  // 创建连接
            connection.setRequestMethod("POST");					// 设置请求方法
            connection.setConnectTimeout(15000);					// 设置连接超时时间
            connection.setReadTimeout(15000 * 10);					// 设置读取超时时间

            //DoOutput设置是否向httpUrlConnection输出，DoInput设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            connection.setDoOutput(true);	// 默认值为：false，当向远程服务器传送数据/写数据时，需要设置为true
            connection.setDoInput(true);	// 默认值为：true，当前向远程服务读取数据时，设置为true，该参数可有可无

			// 设置通用的请求属性
			if (CollectionUtil.isNotEmpty(headMap)) {
				for (Map.Entry<String, String> entry : headMap.entrySet()) {
					String key = entry.getKey();
					String value = entry.getValue();
					connection.setRequestProperty(key, value);
				}
			} else {
				// 使用默认请求属性
				connection.setRequestProperty("accept", "*/*");
				connection.setRequestProperty("connection", "Keep-Alive");
				connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
				connection.setRequestProperty("Charset", "UTF-8");
			}

            // 拼装参数
            if (StringUtils.isNotEmpty(param)) {
                os = connection.getOutputStream();  // 设置参数
                os.write(param.getBytes(StandardCharsets.UTF_8)); // 拼装参数
            }

			// 读取响应头
			Map<String, List<String>> headerFields = connection.getHeaderFields();

			// 读取响应体
			is = connection.getInputStream();
			if (null != is) {
				br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
				String temp = null;
				while (null != (temp = br.readLine())) {
					result.append(temp);
				}
			}

			httpResultVo.setRespondCode(connection.getResponseCode());
			httpResultVo.setRespondHeader(headerFields);
			httpResultVo.setRespondBody(result.toString());

            log.info("[第三方接口]URL：{}, 请求参数：{}，响应头：{}，响应码：{}，响应数据:{}",
					url,
					param,
					headerFields,
					connection.getResponseCode(),
					result);

        } catch (IOException e) {
            log.error("[第三方接口]请求报错：URL：{}", httpUrl, e);
            throw new Exception(e);
        } finally {
            //关闭连接
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //关闭连接
            connection.disconnect();
        }
        return httpResultVo;
    }



	public static String doGet(String httpUrl, Map<String, String> param) throws Exception {

        //链接
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        StringBuffer result = new StringBuffer();
        try {
            URIBuilder builder = new URIBuilder(httpUrl);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            httpUrl = builder.build().toString();
            // 创建连接
            URL url = new URL(httpUrl);
            connection = (HttpURLConnection) url.openConnection();
            // 设置请求方式
            connection.setRequestMethod("GET");
            // 设置连接超时时间
            connection.setConnectTimeout(15000);
            connection.setReadTimeout(15000);
			connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:107.0) Gecko/20100101 Firefox/107.0");

			// 开始连接
            connection.connect();
            // 获取响应数据
            if (connection.getResponseCode() == 200) {
                // 获取返回的数据
                is = connection.getInputStream();
                if (null != is) {
                    br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                    String temp = null;
                    while (null != (temp = br.readLine())) {
                        result.append(temp);
                    }
                }
            }

            log.info("[第三方接口]完整URL：{}, 响应码：{}，响应数据:{}", httpUrl, connection.getResponseCode(), result);
        } catch (IOException | URISyntaxException e) {
			log.error("[第三方接口]完整URL：{}, 响应码：{}，响应数据:{}", httpUrl, connection.getResponseCode(), result);
            throw new Exception(e);
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //关闭远程连接
            connection.disconnect();
        }
        return result.toString();
    }

}
